/**
 * 认证相关工具函数
 */

// Token相关操作
const TOKEN_KEY = "blm_token";
const USER_INFO_KEY = "blm_user_info";
const USER_ROLE_KEY = "blm_user_role";
const TOKEN_EXPIRY_KEY = "blm_token_expiry";
const REMEMBER_ME_KEY = "blm_remember_me";
const REMEMBERED_USERNAME_KEY = "blm_remembered_username";
const REMEMBERED_PASSWORD_KEY = "blm_remembered_password";

// 默认过期时间为一周（7天）
const DEFAULT_TOKEN_EXPIRY = 7 * 24 * 60 * 60 * 1000; // 7天，单位：毫秒

/**
 * 获取Token
 */
export function getToken(): string | null {
  return localStorage.getItem(TOKEN_KEY);
}

/**
 * 设置Token
 * @param token
 * @param expiryTime 过期时间（毫秒），默认为一周
 */
export function setToken(
  token: string,
  expiryTime: number = DEFAULT_TOKEN_EXPIRY
): void {
  localStorage.setItem(TOKEN_KEY, token);

  // 设置token过期时间
  const expiryDate = new Date().getTime() + expiryTime;
  localStorage.setItem(TOKEN_EXPIRY_KEY, expiryDate.toString());
}

/**
 * 移除Token
 */
export function removeToken(): void {
  localStorage.removeItem(TOKEN_KEY);
  localStorage.removeItem(TOKEN_EXPIRY_KEY);
}

/**
 * 检查用户是否已登录
 */
export function isAuthenticated(): boolean {
  const token = getToken();
  if (!token) return false;

  // 检查token是否过期
  const expiryTime = localStorage.getItem(TOKEN_EXPIRY_KEY);
  if (expiryTime) {
    const expiryDate = parseInt(expiryTime);
    if (new Date().getTime() > expiryDate) {
      // Token已过期，清除
      removeToken();
      removeUserInfo();
      removeUserRole();
      return false;
    }
  }

  return true;
}

/**
 * 获取用户信息
 */
export function getUserInfo(): any {
  const userInfo = localStorage.getItem(USER_INFO_KEY);
  return userInfo ? JSON.parse(userInfo) : null;
}

/**
 * 获取当前用户ID（从用户信息或JWT token中获取）
 */
export function getUserId(): string | null {
  // 先尝试从用户信息中获取ID
  const userInfo = getUserInfo();
  if (userInfo && userInfo.id) {
    return userInfo.id;
  }

  // 如果用户信息中没有ID，尝试从JWT token中解析
  const token = getToken();
  if (token) {
    const decoded = parseJwt(token);
    if (decoded && (decoded.userId || decoded.id || decoded.sub)) {
      return decoded.userId || decoded.id || decoded.sub;
    }
  }

  return null;
}

/**
 * 获取骑手ID（专用于骑手角色）
 */
export function getRiderId(): string | null {
  if (!isRider()) {
    return null;
  }
  return getUserId();
}

/**
 * 设置用户信息
 * @param userInfo
 */
export function setUserInfo(userInfo: any): void {
  localStorage.setItem(USER_INFO_KEY, JSON.stringify(userInfo));
}

/**
 * 移除用户信息
 */
export function removeUserInfo(): void {
  localStorage.removeItem(USER_INFO_KEY);
}

/**
 * 获取用户角色
 */
export function getUserRole(): string | null {
  return localStorage.getItem(USER_ROLE_KEY);
}

/**
 * 设置用户角色
 * @param role
 */
export function setUserRole(role: string): void {
  localStorage.setItem(USER_ROLE_KEY, role);
}

/**
 * 移除用户角色
 */
export function removeUserRole(): void {
  localStorage.removeItem(USER_ROLE_KEY);
}

/**
 * 检查是否已登录
 */
export function isLoggedIn(): boolean {
  return !!getToken();
}

// 检查用户是否是管理员
export const isAdmin = (): boolean => {
  const role = getUserRole()?.toUpperCase(); // 将获取到的角色转换为大写
  return role === "ADMIN" || role === "ADMINISTRATOR" || role === "ROLE_ADMIN"; // 与大写角色进行比较，并添加 ROLE_ADMIN
};

// 检查用户是否是商家
export const isMerchant = (): boolean => {
  const role = getUserRole();
  console.log(`检查商家角色，当前角色: ${role}`);

  if (!role) {
    console.log("未找到用户角色");
    return false;
  }

  const roleLower = role.toLowerCase();
  const isMerchantRole =
    roleLower === "merchant" ||
    roleLower === "business" ||
    roleLower === "role_merchant" ||
    roleLower.includes("merchant") ||
    roleLower.includes("business");

  console.log(`角色判断结果: ${isMerchantRole}`);
  return isMerchantRole;
};

// 检查用户是否是顾客/普通用户
export const isUser = (): boolean => {
  const role = getUserRole();
  console.log(`检查顾客角色，当前角色: ${role}`);

  if (!role) {
    console.log("未找到用户角色");
    return false;
  }

  const roleLower = role.toLowerCase();
  const isUserRole =
    roleLower === "user" ||
    roleLower === "customer" ||
    roleLower === "role_user" ||
    roleLower.includes("user") ||
    roleLower.includes("customer");

  console.log(`角色判断结果: ${isUserRole}`);
  return isUserRole;
};

// 检查用户是否是骑手
export const isRider = (): boolean => {
  const role = getUserRole();
  console.log(`检查骑手角色，当前角色: ${role}`);

  if (!role) {
    console.log("未找到用户角色");
    return false;
  }

  const roleLower = role.toLowerCase();
  const isRiderRole =
    roleLower === "rider" ||
    roleLower === "delivery" ||
    roleLower === "role_rider" ||
    roleLower.includes("rider") ||
    roleLower.includes("delivery");

  console.log(`骑手角色判断结果: ${isRiderRole}`);
  return isRiderRole;
};

/**
 * 清除所有认证信息，但保留记住的登录信息
 */
export function clearAuth(): void {
  // 保存记住的登录信息
  const isRemembered = isRememberMe();
  const rememberedUsername = getRememberedUsername();
  const rememberedPassword = getRememberedPassword();

  // 清除token和用户信息
  removeToken();
  removeUserInfo();
  removeUserRole();

  // 如果之前设置了记住登录，则恢复
  if (isRemembered && rememberedUsername) {
    setRememberMe(rememberedUsername, rememberedPassword || "", true);
  }

  console.log("已清除认证信息，保留记住的登录信息:", isRemembered);
}

/**
 * 设置记住密码
 * @param username 用户名
 * @param password 密码（注意：实际应用中应考虑加密存储）
 * @param remember 是否记住
 */
export function setRememberMe(
  username: string,
  password: string,
  remember: boolean
): void {
  if (remember) {
    localStorage.setItem(REMEMBER_ME_KEY, "true");
    localStorage.setItem(REMEMBERED_USERNAME_KEY, username);
    // 实际应用中应该对密码进行加密处理，这里简单处理
    const encodedPassword = btoa(password); // 使用Base64编码，不是真正的加密
    localStorage.setItem(REMEMBERED_PASSWORD_KEY, encodedPassword);
  } else {
    clearRememberMe();
  }
}

/**
 * 清除记住的登录信息
 */
export function clearRememberMe(): void {
  localStorage.removeItem(REMEMBER_ME_KEY);
  localStorage.removeItem(REMEMBERED_USERNAME_KEY);
  localStorage.removeItem(REMEMBERED_PASSWORD_KEY);
}

/**
 * 检查是否记住了登录信息
 */
export function isRememberMe(): boolean {
  return localStorage.getItem(REMEMBER_ME_KEY) === "true";
}

/**
 * 获取记住的用户名
 */
export function getRememberedUsername(): string | null {
  return localStorage.getItem(REMEMBERED_USERNAME_KEY);
}

/**
 * 获取记住的密码
 */
export function getRememberedPassword(): string | null {
  const encodedPassword = localStorage.getItem(REMEMBERED_PASSWORD_KEY);
  if (encodedPassword) {
    try {
      return atob(encodedPassword); // 解码Base64
    } catch (e) {
      console.error("密码解码失败", e);
      return null;
    }
  }
  return null;
}

// 解析JWT token (不验证签名)
export const parseJwt = (token: string): any => {
  try {
    const base64Url = token.split(".")[1];
    const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
    const jsonPayload = decodeURIComponent(
      window
        .atob(base64)
        .split("")
        .map(function (c) {
          return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
        })
        .join("")
    );
    return JSON.parse(jsonPayload);
  } catch (e) {
    console.error("Invalid token format", e);
    return null;
  }
};

// 检查token是否过期
export const isTokenExpired = (): boolean => {
  const token = getToken();
  console.log(`检查token是否过期，token存在: ${!!token}`);

  if (!token) return true;

  try {
    // 优先使用本地存储的过期时间
    const expiryTime = localStorage.getItem(TOKEN_EXPIRY_KEY);
    console.log(`本地存储的过期时间: ${expiryTime}`);

    if (expiryTime) {
      const expiryDate = parseInt(expiryTime);
      // 确保expiryDate是一个有效的数字
      if (!isNaN(expiryDate)) {
        const isExpired = Date.now() > expiryDate;
        console.log(
          `使用本地存储的过期时间，过期时间: ${new Date(
            expiryDate
          ).toLocaleString()}, 当前时间: ${new Date().toLocaleString()}, 是否过期: ${isExpired}`
        );

        // 如果时间差小于5秒，可能是时钟误差，视为未过期
        if (isExpired && Date.now() - expiryDate < 5000) {
          console.log("时间差小于5秒，视为未过期");
          return false;
        }

        return isExpired;
      } else {
        console.log("本地存储的过期时间无效，尝试从JWT中解析");
      }
    }

    // 如果没有本地存储的过期时间或解析失败，尝试从JWT中解析
    const decoded = parseJwt(token);
    console.log("JWT解析结果:", decoded);

    if (!decoded) {
      console.log("JWT解析失败，假设token有效");
      // 如果解析失败，假设token有效，避免错误登出
      return false;
    }

    // 检查是否有exp字段
    if (!decoded.exp) {
      console.log("JWT中没有exp字段，假设token有效");
      return false;
    }

    // 将过期时间转换为毫秒并与当前时间比较
    const currentTime = Date.now() / 1000;
    const isExpired = decoded.exp < currentTime;
    console.log(
      `使用JWT中的过期时间，过期时间: ${new Date(
        decoded.exp * 1000
      ).toLocaleString()}, 当前时间: ${new Date().toLocaleString()}, 是否过期: ${isExpired}`
    );

    // 如果时间差小于5秒，可能是时钟误差，视为未过期
    if (isExpired && currentTime - decoded.exp < 5) {
      console.log("时间差小于5秒，视为未过期");
      return false;
    }

    return isExpired;
  } catch (e) {
    console.error("Error checking token expiration", e);
    // 出错时假设token有效，避免错误登出用户
    return false;
  }
};

// 调试函数：检查token状态并返回详细信息
export const debugTokenStatus = (): any => {
  const token = getToken();
  if (!token) {
    return {
      valid: false,
      reason: "TOKEN_MISSING",
      message: "Token不存在",
    };
  }

  try {
    // 检查本地存储的过期时间
    const expiryTime = localStorage.getItem(TOKEN_EXPIRY_KEY);
    let localExpiryStatus: any = null;

    if (expiryTime) {
      const expiryDate = parseInt(expiryTime);
      if (!isNaN(expiryDate)) {
        const timeDiff = expiryDate - Date.now();
        localExpiryStatus = {
          expired: Date.now() > expiryDate,
          expiryDate: new Date(expiryDate).toLocaleString(),
          currentTime: new Date().toLocaleString(),
          timeDiff: timeDiff,
          timeDiffFormatted: `${Math.floor(
            Math.abs(timeDiff) / 1000 / 60
          )} 分钟 ${Math.floor(Math.abs(timeDiff) / 1000) % 60} 秒`,
        };
      }
    }

    // 检查JWT中的过期时间
    const decoded = parseJwt(token);
    let jwtExpiryStatus: any = null;

    if (decoded && decoded.exp) {
      const currentTime = Date.now() / 1000;
      const timeDiff = (decoded.exp - currentTime) * 1000;
      jwtExpiryStatus = {
        expired: decoded.exp < currentTime,
        expiryDate: new Date(decoded.exp * 1000).toLocaleString(),
        currentTime: new Date().toLocaleString(),
        timeDiff: timeDiff,
        timeDiffFormatted: `${Math.floor(
          Math.abs(timeDiff) / 1000 / 60
        )} 分钟 ${Math.floor(Math.abs(timeDiff) / 1000) % 60} 秒`,
      };
    }

    // 检查token的有效性
    const isExpired = isTokenExpired();

    // 确定过期原因
    let reason: string | null = null;
    if (isExpired) {
      if (localExpiryStatus && localExpiryStatus.expired) {
        reason = "LOCAL_EXPIRY";
      } else if (jwtExpiryStatus && jwtExpiryStatus.expired) {
        reason = "JWT_EXPIRY";
      } else {
        reason = "UNKNOWN";
      }
    }

    return {
      valid: !isExpired,
      token:
        token.substring(0, 10) + "..." + token.substring(token.length - 10),
      tokenLength: token.length,
      localExpiryStatus,
      jwtExpiryStatus,
      userRole: getUserRole(),
      reason,
      decoded: decoded,
    };
  } catch (error: any) {
    return {
      valid: false,
      reason: "ERROR",
      message: "检查token时发生错误",
      error: error.toString(),
    };
  }
};

// 将调试日志保存到localStorage
export const saveDebugLog = (type: string, message: any): void => {
  try {
    // 获取现有日志
    const logsJson = localStorage.getItem("blm_debug_logs") || "[]";
    const logs = JSON.parse(logsJson);

    // 添加新日志，包含时间戳
    logs.push({
      time: new Date().toLocaleString(),
      type,
      message: typeof message === "object" ? JSON.stringify(message) : message,
    });

    // 只保留最近的100条日志
    const recentLogs = logs.slice(-100);

    // 保存回localStorage
    localStorage.setItem("blm_debug_logs", JSON.stringify(recentLogs));
  } catch (error) {
    console.error("保存调试日志失败:", error);
  }
};

// 获取保存的调试日志
export const getDebugLogs = (): any[] => {
  try {
    const logsJson = localStorage.getItem("blm_debug_logs") || "[]";
    return JSON.parse(logsJson);
  } catch (error) {
    console.error("获取调试日志失败:", error);
    return [];
  }
};

// 清除调试日志
export const clearDebugLogs = (): void => {
  localStorage.removeItem("blm_debug_logs");
};
